--module HLibcell.HFunc where


module HLibcell.HFunc (
    HVertex(HVertex),
    HHalfFace(HHalfFace),
    HFace(HFace),
    HCell(HCell),
    HMesh(HMesh),
    Eq,
    hvertex_get_id ,
    hvertex_get_point,
    hvertex_get_cells,
    hvertex_get_faces,
    hvertex_get_trait,
    hhalfface_get_id,
    hhalfface_get_vertices,
    hhalfface_get_cell,
    hhalfface_get_face,
    hhalfface_get_traits,
    hface_get_id,
    hface_get_vertices,
    hface_get_halffaces1,
    hface_get_halffaces2,
    hface_get_traits,
    hcell_get_id,
    hcell_get_vertices,
    hcell_get_halffaces ,
    hcell_get_traits ,
    hmesh_get_vertices,
    hmesh_get_halffaces,
    hmesh_get_faces,
    hmesh_get_cells,

    hmesh_get_vertex,
    hmesh_get_halfface,
    hmesh_get_face,
    hmesh_get_cell,
    hmesh_get_facev,
    hmesh_get_cellv,
    hmesh_get_cellf,
    hmesh_get_dimension,
    hmesh_get_back_dim,
    hmesh_get_simplex,
    hmesh_get_manifold_require ,
    hmesh_create_vertexv,
    hmesh_create_facev,
    hmesh_create_facevi,
    hmesh_create_halfface,
    hmesh_create_halffacei,
    hmesh_create_cellf,
    hmesh_create_cellfi,
    hmesh_create_cellvi,
    hmesh_create_cellv,

    hmesh_delete_celli,
    hmesh_replace_vmap ,
    hmesh_replace_hfmap,
    hmesh_replace_fmap,
    hmesh_replace_cmap,
    hmesh_replace_vnid,
    hmesh_replace_hfnid,
    hmesh_replace_fnid,
    hmesh_replace_cnid,
    hmesh_replace_dimension,
    hmesh_replace_simplex,
    hmesh_replace_manifold_require, 
    hmesh_create ,
    hmesh_num_v,
    hmesh_num_f,
    hmesh_num_c

     )where
import Data.List
import qualified Data.Map.Lazy as HMap
import qualified Data.IntMap.Lazy as IMap



data HVertex v  = HVertex {
    hvertex_get_id:: Int,
    hvertex_get_point:: [Double], 
    hvertex_get_cells:: [Int],
    hvertex_get_faces:: [Int],
    hvertex_get_trait:: (Maybe v)
} deriving (Show)

data HHalfFace hf =HHalfFace{
    hhalfface_get_id:: Int,
    hhalfface_get_vertices:: [Int],
    hhalfface_get_cell:: Int,
    hhalfface_get_face:: Int,
    hhalfface_get_traits:: (Maybe hf)
}deriving (Show)

data HFace f=HFace{
    hface_get_id:: Int,
    hface_get_vertices:: [Int],
    hface_get_halffaces1:: Int,
    hface_get_halffaces2:: Int,
    hface_get_traits:: (Maybe f)
}deriving (Show)

data HCell c=HCell{
    hcell_get_id:: Int,
    hcell_get_vertices:: [Int],
    hcell_get_halffaces:: [Int],
    hcell_get_traits:: (Maybe c)
}deriving (Show)

data HMesh m v hf f c=HMesh{
    hmesh_get_vertices:: (IMap.IntMap (HVertex v)),
    hmesh_get_halffaces:: (IMap.IntMap (HHalfFace hf)),
    hmesh_get_faces:: (IMap.IntMap (HFace f)),
    hmesh_get_cells:: (IMap.IntMap (HCell c)),
    hmesh_get_vertices_name_id:: Int,
    hmesh_get_halffaces_name_id:: Int,
    hmesh_get_faces_name_id:: Int,
    hmesh_get_cells_name_id:: Int, 
    hmesh_get_dimension:: Int,
    hmesh_get_simplex:: Bool,
    hmesh_get_manifold_require:: Bool,
    hmesh_get_traits:: (Maybe m)
}deriving (Show)


instance Eq (HVertex v) where
    (HVertex id1 point1 _ _ _)==(HVertex id2 point2 _ _ _)=
        (id1==id2)&&(point1==point2)

instance Eq (HHalfFace hf) where
    (HHalfFace id1 _ _ _ _)==(HHalfFace id2 _ _ _ _)=
        (id1==id2)

instance Eq (HFace f) where
    (HFace id1 _ _ _ _)==(HFace id2 _ _ _ _)=
        (id1==id2)

instance Eq (HCell c) where
    (HCell id1 _ _ _)==(HCell id2 _ _ _)=
        id1==id2



list_union::(Eq a)=>[a]->[a]->[a]
list_union [] x2=x2
list_union (x:xs) x2=if elem x x2
    then list_union xs x2
    else
        list_union xs (x:x2) 

        
list_intersection::(Eq a)=>[a]->[a]->[a]
list_intersection [] x1=[]
list_intersection x1 []=[]
list_intersection x1 x2=[i|i<- x1,elem i x2]


hmesh_get_vertex :: HMesh m v hf f c -> Int -> Maybe (HVertex v)
hmesh_get_vertex mesh id=mv
    where
        vmap=hmesh_get_vertices mesh
        mv=IMap.lookup id vmap

hmesh_get_halfface :: HMesh m v hf f c->Int->Maybe (HHalfFace hf)
hmesh_get_halfface mesh id=mhf
    where
        hfmap=hmesh_get_halffaces mesh
        mhf=IMap.lookup id hfmap

hmesh_get_face::HMesh m v hf f c->Int->Maybe (HFace f)
hmesh_get_face mesh id=mf
    where
        fmap=hmesh_get_faces mesh
        mf=IMap.lookup id fmap

hmesh_get_cell::HMesh m v hf f c->Int ->Maybe (HCell c)
hmesh_get_cell mesh id= mc
    where
        cmap=hmesh_get_cells mesh
        mc=IMap.lookup id cmap
        
hmesh_get_facev::HMesh m v hf f c->[HVertex v]->Maybe (HFace f)
hmesh_get_facev mesh []=Nothing
hmesh_get_facev mesh vs=myfun mesh fs
    where
        ffs= map hvertex_get_faces vs
        fs=foldl' list_intersection (head ffs) $ tail ffs
        myfun:: HMesh m v hf f c->[Int]->Maybe (HFace f)
        myfun mmesh []=Nothing
        myfun mmesh xs =hmesh_get_face mmesh (head xs)


hmesh_get_cellv::HMesh m v hf f c->[HVertex v]->Maybe (HCell c)     
hmesh_get_cellv mesh []=Nothing
hmesh_get_cellv mesh vs=myfun mesh cs
    where
        ccs= map hvertex_get_cells vs
        cs=foldl' list_intersection (head ccs)$ tail ccs
        myfun:: HMesh m v hf f c->[Int]->Maybe (HCell c)
        myfun mmesh []=Nothing
        myfun mmesh xs =hmesh_get_cell mmesh (head xs)


hmesh_get_cellf::HMesh m v hf f c->[HFace f ]->Maybe (HCell c)
hmesh_get_cellf mesh []=Nothing
hmesh_get_cellf mesh fs=myfun mesh cs
    where
        myfun1::Maybe (HHalfFace hf)->Int
        myfun1 Nothing= (-1)
        myfun1 x =hhalfface_get_cell ((\(Just a)->a) x)
        myfun2::HMesh m v hf f c-> HFace f->[Int]
        myfun2 mmesh ff=
            let x1= myfun1 $ hmesh_get_halfface mmesh (hface_get_halffaces1 ff)
                x2= myfun1 $ hmesh_get_halfface mmesh (hface_get_halffaces2 ff)
            in (x1:[x2])
        ccs=map (myfun2 mesh) fs
        cs=foldl' list_intersection (head ccs) $ tail ccs 
        myfun:: HMesh m v hf f c->[Int]->Maybe (HCell c)
        myfun mmesh []=Nothing
        myfun mmesh xs =hmesh_get_cell mmesh (head [i|i<-xs,i>=0])


hmesh_get_back_dim::HMesh m v hf f c->Int
hmesh_get_back_dim mesh = length $ hvertex_get_point $snd min1
    where 
        min1=IMap.findMin vers 
        vers=hmesh_get_vertices mesh 



hmesh_create_vertexv::[Double]->HMesh m v hf f c->(HMesh m v hf f c,Maybe(HVertex v))
hmesh_create_vertexv p mesh =(nmesh,Just (nv))
    where
        id= hmesh_get_vertices_name_id mesh
        nv=HVertex id p [] [] Nothing
        vmap= hmesh_get_vertices mesh 
        nvmap=IMap.insert id nv vmap
        nmesh =hmesh_replace_vmap nvmap (hmesh_replace_vnid  (id+1) mesh) 






hmesh_create_facev::[HVertex v]->HMesh m v hf f c->(HMesh m v hf f c,Maybe( HFace f))
hmesh_create_facev [] mesh =(mesh,Nothing)
hmesh_create_facev vs mesh=if ff==Nothing
    then (nmesh,Just nf)
    else
        (mesh,ff)
    where
        myfun::Int->HVertex v->HVertex v
        myfun id1 (HVertex ids point c1 f1 t1) =HVertex ids point c1 (id1:f1) t1
        myfun1::IMap.IntMap (HVertex v)->HVertex v->IMap.IntMap (HVertex v)
        myfun1 map1 v1  = IMap.insert (hvertex_get_id v1) v1 map1  
        id=hmesh_get_faces_name_id mesh
        nf=HFace id (map hvertex_get_id vs) (-1) (-1) Nothing
        ff=hmesh_get_facev mesh vs
        nvs=map (myfun id) vs
        fmap=hmesh_get_faces mesh
        vmap=hmesh_get_vertices mesh
        nfmap=IMap.insert id nf fmap 
        nvmap=foldl' myfun1 vmap nvs
        nmesh=hmesh_replace_vmap nvmap (hmesh_replace_fmap nfmap (hmesh_replace_fnid  (id+1) mesh) )  

hmesh_create_facevi::[Int]->HMesh m v hf f c->(HMesh m v hf f c,Maybe (HFace f))
hmesh_create_facevi [] mesh =(mesh,Nothing)
hmesh_create_facevi vs mesh = hmesh_create_facev  (map ((\(Just x)->x).(hmesh_get_vertex mesh))  vs) mesh

      
hmesh_create_halfface::HFace f->[HVertex v]->HMesh m v hf f c->(HMesh m v hf f c, Maybe (HHalfFace hf))
hmesh_create_halfface  f1 [] mesh=(mesh,Nothing)
hmesh_create_halfface f1 vs mesh=if hf1==Nothing 
    then
        let
            nf=HFace (hface_get_id f1) (hface_get_vertices f1) (id) (hface_get_halffaces2 f1) (hface_get_traits f1) 
            nfmap=IMap.insert (hface_get_id f1) nf fmap
            nmesh1=hmesh_replace_fmap nfmap nmesh 
        in (nmesh1,Just nhf)
    else if hf2==Nothing 
    then
        let
            nf=HFace (hface_get_id f1) (hface_get_vertices f1)  (hface_get_halffaces1 f1) id (hface_get_traits f1) 
            nfmap=IMap.insert (hface_get_id f1) nf fmap
            nmesh1=hmesh_replace_fmap nfmap nmesh  
        in (nmesh1,Just nhf)
    else
        (mesh,Nothing)
    where
        id=hmesh_get_halffaces_name_id mesh
        nhf=HHalfFace id (map hvertex_get_id vs) (-1) (hface_get_id f1) Nothing
        hf1=hmesh_get_halfface mesh $ hface_get_halffaces1 f1
        hf2=hmesh_get_halfface mesh $ hface_get_halffaces2 f1   
        hfmap=hmesh_get_halffaces mesh
        nhfmap=IMap.insert id nhf hfmap
        nmesh=hmesh_replace_hfmap nhfmap. hmesh_replace_hfnid (id+1) $ mesh  
        fmap=hmesh_get_faces mesh

hmesh_create_halffacei::Int->[Int]->HMesh m v hf f c->(HMesh m v hf f c,Maybe (HHalfFace hf))
hmesh_create_halffacei  f1 vs mesh=hmesh_create_halfface ((\(Just x)->x ) $ hmesh_get_face mesh f1) vs1 mesh
    where
        vs1=map ((\(Just x)->x). hmesh_get_vertex mesh) vs


hmesh_create_cellf:: [HHalfFace hf]->HMesh m v hf f c->(HMesh m v hf f c,Maybe (HCell c))
hmesh_create_cellf  [] mesh=(mesh,Nothing)
hmesh_create_cellf  hfs mesh=if cc==Nothing
    then 
        (nmesh,Just c1) 
    else
        (mesh,cc)  
    where
        cc=hmesh_get_cell mesh $ hhalfface_get_cell (head hfs) 
        myfun::Int->HHalfFace hf->HHalfFace hf
        myfun id1 (HHalfFace id2 vers2 c2 f2 t2)=HHalfFace id2 vers2 id1 f2 t2 
        myfun1::Int->HVertex v->HVertex v
        myfun1 id1 (HVertex id2 p c2 f2 t2)=HVertex id2 p (id1:c2) f2 t2
        id=hmesh_get_cells_name_id mesh
        vers=foldl' list_union [] $ (map hhalfface_get_vertices hfs)
        c1=HCell id vers (map hhalfface_get_id hfs) Nothing
        hfmap=hmesh_get_halffaces mesh
        vmap=hmesh_get_vertices mesh
        cmap=hmesh_get_cells mesh
        nhfmap =foldl' (\mm vv ->IMap.insert (hhalfface_get_id vv) vv mm) hfmap $ map (myfun id) hfs  
        ncmap=IMap.insert id c1 cmap
        vers1=map (\x->IMap.lookup x vmap) vers   
        vers2=map (\(Just x)->x) vers1
        nvmap=foldl' (\mm vv->IMap.insert (hvertex_get_id vv) vv mm) vmap $ map (myfun1 id) vers2  
        nmesh = hmesh_replace_vmap nvmap. hmesh_replace_hfmap nhfmap.hmesh_replace_cmap ncmap.hmesh_replace_cnid (id+1)$mesh

hmesh_create_cellfi::[Int]->HMesh m v hf f c->(HMesh m v hf f c,Maybe (HCell c))
hmesh_create_cellfi hfs mesh= hmesh_create_cellf (map ((\(Just x)->x).hmesh_get_halfface mesh) hfs) mesh


myhmesh_create_cell::[Int]->[Int]->HMesh m v hf f c->(HMesh m v hf f c,Maybe(HCell c))
myhmesh_create_cell vs hfs mesh =(nmesh,Just cc)
    where
        myfun::Int->HHalfFace hf->HHalfFace hf
        myfun id1 (HHalfFace id2 vers2 c2 f2 t2)=HHalfFace id2 vers2 id1 f2 t2 
        myfun1::Int->HVertex v->HVertex v
        myfun1 id1 (HVertex id2 p c2 f2 t2)=HVertex id2 p (id1:c2) f2 t2
        vs1=map ((\(Just x)->x).hmesh_get_vertex mesh) vs
        hfs1=map ((\(Just x)->x).hmesh_get_halfface mesh) hfs  
        id=hmesh_get_cells_name_id mesh 
        cc=HCell id vs hfs Nothing
        hfmap=hmesh_get_halffaces mesh
        vmap=hmesh_get_vertices mesh
        cmap=hmesh_get_cells mesh 
        nhfmap =foldl' (\mm vv ->IMap.insert (hhalfface_get_id vv) vv mm) hfmap $ map (myfun id) hfs1
        nvmap=foldl'(\mm vv->IMap.insert (hvertex_get_id vv) vv mm) vmap $ map (myfun1 id) vs1
        ncmap=IMap.insert id cc cmap
        nmesh= hmesh_replace_vmap nvmap. hmesh_replace_hfmap nhfmap.hmesh_replace_cmap ncmap.hmesh_replace_cnid (id+1)$mesh

 

hmesh_create_cellvi::[Int]->HMesh m v hf f c->(HMesh m v hf f c,Maybe(HCell c))
hmesh_create_cellvi  [] mesh=(mesh,Nothing)
hmesh_create_cellvi vs mesh=if cc==Nothing 
    then 
        myhmesh_create_cell vs hfs nmesh  
        --hmesh_create_cellfi  hfs nmesh
    else
        (mesh,cc)
    where
        myfun::Int->Int->[a]->[a]
        myfun size i xs=if size>2&&mod (size-i-1) 2==1
            then 
                (\(y:ys)->(head ys):(y:(tail ys))) xs
            else
                xs 
        myfun1::HMesh m v hf f c->[Int]->(HMesh m v hf f c,Maybe (HHalfFace hf))
        myfun1 mmesh vvs=hmesh_create_halffacei id1 vvs nmmesh
            where
                (nmmesh,ff)=hmesh_create_facevi vvs mmesh 
                id1=hface_get_id $ (\(Just x)->x) ff
        myfun2::(HMesh m v hf f c,[Int])->[Int]->(HMesh m v hf f c,[Int])
        myfun2  (mmesh,hhfs) vvs =(nmmesh,id1:hhfs)
            where
                (nmmesh,nhhf)=myfun1 mmesh vvs
                id1=hhalfface_get_id $ (\(Just x)->x) nhhf 
        cc=hmesh_get_cellv mesh $ map ((\(Just x)->x ).hmesh_get_vertex mesh) vs
        --id=hmesh_get_cells_name_id mesh 
        hfvids=[myfun (length vs) i  [vs !!j|j<-[0..(length vs-1)],j/=i]|i<-[0..(length vs-1)]]
        (nmesh,hfs)=foldl' myfun2 (mesh,[]) hfvids

hmesh_create_cellv::[HVertex v]->HMesh m v hf f c->(HMesh m v hf f c,Maybe(HCell c))
hmesh_create_cellv  vs mesh= hmesh_create_cellvi (map hvertex_get_id vs) mesh






-- hmesh_delete_vertex::HMesh m v hf f c->HVertex v->HMesh m v hf f c
-- hmesh_delete_vertex mesh vv=


hmesh_delete_face::HFace f ->HMesh m v hf f c->HMesh m v hf f c
hmesh_delete_face  ff mesh=if hmesh_get_manifold_require mesh 
    then 
        nmesh1 
    else 
        nmesh2   
    where
        hf1=hmesh_get_halfface mesh $ hface_get_halffaces1 ff
        hf2=hmesh_get_halfface mesh $ hface_get_halffaces2 ff
        nmesh1= foldl' (\m x->if x==Nothing then m else 
            hmesh_delete_celli (hhalfface_get_cell $ (\(Just y)->y) x) m) mesh [hf1,hf2]
        nmesh2=my_delete_face ff nmesh1 

         

--

my_delete_face::HFace f->HMesh m v hf f c->HMesh m v hf f c
my_delete_face f1 mesh=nmesh
    where
        vids= hface_get_vertices f1
        vs=map ((\(Just x)->x).hmesh_get_vertex mesh) vids 
        vmap=hmesh_get_vertices mesh 
        fmap=hmesh_get_faces mesh
        nfmap=IMap.delete (hface_get_id f1) fmap 
        v_remove_f::HFace f->HVertex v->HVertex v
        v_remove_f f2 (HVertex vid vp vc vf vt) =HVertex vid vp vc (delete (hface_get_id f2) vf ) vt
        nvs=map (v_remove_f f1) vs
        nvmap=foldl' (\mm vv->IMap.insert (hvertex_get_id vv) vv mm) vmap nvs
        nmesh=hmesh_replace_vmap nvmap.hmesh_replace_fmap nfmap $ mesh


my_delete_facei::Int->HMesh m v hf f c->HMesh m v hf f c
my_delete_facei id mesh=if ff==Nothing
    then mesh
    else my_delete_face f1 mesh 
    where
        ff=hmesh_get_face mesh id
        f1=(\(Just x)->x) ff 


hmesh_delete_cell::HCell c->HMesh m v hf f c->HMesh m v hf f c
hmesh_delete_cell cc mesh =if hmesh_get_manifold_require mesh 
    then 
        foldr  my_delete_facei nmesh fids1
    else
        nmesh
    where
        cmap=hmesh_get_cells mesh
        ncmap=IMap.delete (hcell_get_id cc) cmap       
        hfmap=hmesh_get_halffaces mesh
        hfids=hcell_get_halffaces cc  
        nhfmap=foldr (\vv mm->IMap.delete vv mm) hfmap hfids
        vmap=hmesh_get_vertices mesh
        vids=hcell_get_vertices cc 
        vers=map ((\(Just x)->x).hmesh_get_vertex mesh ) vids
        v_remove_c::HCell c->HVertex v->HVertex v
        v_remove_c c4  (HVertex vid vp vc vf vt)=HVertex vid vp (delete (hcell_get_id c4) vc) vf vt
        nvers=map (v_remove_c cc) vers
        nvmap=foldr (\vv mm->IMap.insert (hvertex_get_id vv) vv mm) vmap nvers
        nmesh=hmesh_replace_vmap nvmap.hmesh_replace_hfmap nhfmap.hmesh_replace_cmap ncmap $ mesh
        hfs=map ((\(Just x)->x).hmesh_get_halfface mesh) hfids   
        fids=map hhalfface_get_face hfs
        myfun :: HFace f->Bool
        myfun (HFace fid fv fhf1 fhf2 ft)=if hmesh_get_halfface nmesh fhf1==Nothing && hmesh_get_halfface nmesh fhf2==Nothing
            then True
            else False
        fids1=[i|i<-fids,myfun (((\(Just x)->x).hmesh_get_face nmesh) i)]


hmesh_delete_celli::Int ->HMesh m v hf f c->HMesh m v hf f c
hmesh_delete_celli id mesh=if cc==Nothing
    then mesh
    else hmesh_delete_cell ((\(Just x)->x) cc) mesh
    where
        cc=hmesh_get_cell mesh id


hmesh_replace_vmap:: IMap.IntMap (HVertex v )->HMesh m v hf f c->HMesh m v  hf f c
hmesh_replace_vmap nvmap (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt) =
    HMesh nvmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt 

hmesh_replace_hfmap::IMap.IntMap (HHalfFace hf )->HMesh m v hf f c-> HMesh m v hf f c
hmesh_replace_hfmap nhfmap (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt) =
    HMesh vmap nhfmap fmap cmap vnid hfnid fnid cnid dim sim man mt 

hmesh_replace_fmap::IMap.IntMap (HFace f )->HMesh m v hf f c->HMesh m v hf f  c
hmesh_replace_fmap nfmap (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt) =
    HMesh vmap hfmap nfmap cmap vnid hfnid fnid cnid dim sim man mt


hmesh_replace_cmap::IMap.IntMap (HCell c )->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_cmap ncmap (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt) =
    HMesh vmap hfmap fmap ncmap vnid hfnid fnid cnid dim sim man mt

hmesh_replace_vnid::Int->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_vnid nvnid (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt) =
    HMesh vmap hfmap fmap cmap nvnid hfnid fnid cnid dim sim man mt


hmesh_replace_hfnid::Int->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_hfnid  nhfnid (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt)=
    HMesh vmap hfmap fmap cmap vnid nhfnid fnid cnid dim sim man mt


hmesh_replace_fnid::Int->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_fnid nfnid (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt) =
    HMesh vmap hfmap fmap cmap vnid hfnid nfnid cnid dim sim man mt

hmesh_replace_cnid::Int->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_cnid  ncnid (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt)=
    HMesh vmap hfmap fmap cmap vnid hfnid fnid ncnid dim sim man mt

hmesh_replace_dimension::Int->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_dimension ndim (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt)= 
    HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid ndim sim man mt

hmesh_replace_simplex::Bool->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_simplex nsim (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt)= 
    HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim nsim man mt

hmesh_replace_manifold_require::Bool->HMesh m v hf f c->HMesh m v hf f c
hmesh_replace_manifold_require nman (HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim man mt)= 
    HMesh vmap hfmap fmap cmap vnid hfnid fnid cnid dim sim nman mt


hmesh_create:: HMesh m v hf f c
hmesh_create =(HMesh (IMap.empty::IMap.IntMap (HVertex v)) 
    (IMap.empty::IMap.IntMap (HHalfFace hf)) (IMap.empty::IMap.IntMap (HFace f)) 
    (IMap.empty::IMap.IntMap (HCell c)) 0 0 0 0 2 True True Nothing)

hmesh_num_v::HMesh m v hf f c->Int
hmesh_num_v mesh=IMap.size $ hmesh_get_vertices mesh 


hmesh_num_f::HMesh m v hf f c->Int
hmesh_num_f mesh =IMap.size $ hmesh_get_faces mesh


hmesh_num_c::HMesh m v hf f c->Int
hmesh_num_c mesh =IMap.size $ hmesh_get_cells mesh

